#pragma once

/*
 * 状态机的基类
 * 需要实现：raft_core（ raft 核心层 ）对其直接调用（即应用日志条目到状态机）
 */

#include <memory>
#include <string>

#include "raft_middleware/rpc_proto/middleware_rpc.grpc.pb.h"
#include "raft_utils/Command.h"

namespace raft::state_machine {
    class StateMachine : public middleware_rpc_proto::MiddlewareService::Service {
    public:
        virtual ~StateMachine() = default;
        /*
         * 应用日志到到状态机
         * 返回 true 代表被应用，false 代表无法应用，此条日志被忽略
         * 若结果为 false 则 msg 返回原因，true 则 msg 返回所需参数
         */
        virtual bool apply(std::shared_ptr<utils::Command> &command, std::string *msg) = 0;

        /* --- raft middleware 调用部分 --- */
        // 给 raft_middleware 进行读操作
        virtual grpc::Status execute_command(grpc::ServerContext *context,
                                             const middleware_rpc_proto::ExecuteCommand *request,
                                             middleware_rpc_proto::ExecuteCommandReply *reply) = 0;


        // 生成状态机的快照
        [[nodiscard]] virtual std::string snapshot() = 0;

        // 从快照回复状态
        virtual void restore(const std::string &snapshot) = 0;
    };
}// namespace raft::state_machine
